package tools.chapter19;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.*;

/**
 * @author Kevin
 * @date 2020/4/9 20:32
 */
public class useCountDownLatchOrCyclicBarrier {
    // 订单队列
    Vector<Order> pos;
    // 派送单队列
    Vector<Order> dos;
    //差异
    Different diff;
    // 执行回调的线程池
    Executor executor = Executors.newFixedThreadPool(1);
    //线程同步器
    final CyclicBarrier barrier = new CyclicBarrier(2, () -> {
        executor.execute(() -> check());
    });

    //使用CountDownLatch
    public void vaildOrder1() throws InterruptedException {
        //创建两个线程的线程池
        Executor executors = Executors.newFixedThreadPool(2);
        boolean hasTODO = true;
        while(hasTODO) {
            // 计数器初始化为2
            CountDownLatch latch = new CountDownLatch(2);
            //查询未对账订单
            executors.execute(() -> {
                pos = getPOrders();
                latch.countDown();
            });
            //查询派送单
            executors.execute(() -> {
                dos = getDOrders();
                latch.countDown();
            });
            //等待两个查询操作结束
            latch.await();

            //执行对账操作
            diff = check(pos, dos);
            //差异写入差异库
            save(diff);
        }
    }

    //以下是使用CyclicBarrier的
    public void check() {
        Order p = pos.remove(0);
        Order d = dos.remove(0);
        //执行对账操作
        diff = check(pos, dos);
        //差异写入差异库
        save(diff);
    }

    public void checkAll() {
        //代表存在未查询订单
        boolean hasTODO = true;
        //循环查询订单库
        Thread T1 = new Thread(() -> {
            while (hasTODO) {
                //查询订单库
                pos.addAll(getPOrders());
                //等待
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        });
        T1.start();
        //循环查询派送单库
        Thread T2 = new Thread(() -> {
           while (hasTODO) {
               dos.addAll(getDOrders());
               try {
                   barrier.await();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               } catch (BrokenBarrierException e) {
                   e.printStackTrace();
               }
           }
        });
        T2.start();
    }



    public Vector<Order> getPOrders() { return new Vector<Order>();}
    public Vector<Order> getDOrders() {return new Vector<Order>();}
    public Different check(Vector<Order> pos, Vector<Order> dos) {return new Different();}
    public void save(Different diff){}
    class Order{}
    class Different{}
}
